enum module_item_type {
    MI_UNDEFINED = 0,
    MI_CPU_CSRRW = 1,
    MI_CPU_EXHDLR = 2,
    MI_CPU_DECODER = 3,
    MI_DEV_CSRRW = 4,
    MI_MEM_PHYRW = 5,
    MI_MEM_VIRTRW = 6
};

enum module_stat {
    MOD_STAT_UNINITIALIZED,
    MOD_STAT_STOPPED,
    MOD_STAT_RUNNING,
    MOD_STAT_PAUSED
};

struct module_item {
    magic_t magic;
    modid_t modid;
    enum module_item_type type;
    void * context;
    struct module * base;
    union {
        void * ptr;
        cpu_csrrw cpu_csrrw_func;
        cpu_exhdlr cpu_exhdlr_func;
        cpu_decoder cpu_decoder_func;
        dev_csrrw dev_csrrw_func;
        mem_virtrw mem_virtrw_func;
        mem_phyrw mem_phyrw_func;
    } func;
};

struct module {
    magic_t magic;
    modid_t modid;
    enum module_stat stat;
    #define MAX_MOD_NAMESZ 256
    char name[MAX_MOD_NAMESZ];
    void * context;
    mod_fn init; // 初始化 ctx
    mod_fn start; // 启动
    mod_fn stop; // 终止
    mod_fn pause; // 暂停
    mod_fn resume; // 恢复
    // mod_fn migratable; // 当前状态是否可迁移
    mod_exfn modctl; //mod 控制接口
    struct {
    count_t item_n;
    struct module_item item_list[MAX_MOD_ITEM];
    } items;
};

struct modlist {
    struct module * list[MAX_MODS];
    uint64 mod_n;
};

#define xglue(x,y) x##y
#define glue(x,y) xglue(x, y)

/*
 * 添加 Module Item
 * 1. 寻找field接入点空闲位置(表中modid == MODID_INVAILD)
 * 2. 将item.modid加入field_modid, item.func加入field_func,item.context加入field_ctx
 */
#define add_module_item(target,field,item) { \
    count_t __tmp_i, __tmp_j;\
    __tmp_j = MAX_MOD_ITEM;\
    for (__tmp_i = 0; __tmp_i < MAX_MOD_ITEM; __tmp_i++) { \
        if (target->mods.glue(field,_modid)[__tmp_i] == MODID_INVAILD) { \
            __tmp_j = __tmp_i; \
            break;\
        }\
    }\
    if (__tmp_j >= MAX_MOD_ITEM) {\
        stat |= ERR_NRITEM;\
    } else {\
        target->mods.glue(field,_func)[__tmp_j] = item.func.glue(glue(target,_),glue(field,_func));\
        target->mods.glue(field,_modid)[__tmp_j] = item.modid;\
        target->mods.glue(field,_ctx)[__tmp_j] = item.context;\
        target->mods.glue(field,_base)[__tmp_j] = item.base;\
    }\
}

/*
 * 移除 Module Item 
 * 1. 寻找field_modid == modid的mod项
 * 2. 将匹配的mod项field_modid置MODID_INVALID
 * 3. 将后面所有的field_modid, field_ctx, field_func前移
 */
#define remove_module_item(target,field,modid){\
    count_t __tmp_i, __tmp_j;\
    for (__tmp_i = 0; __tmp_i < MAX_MOD_ITEM; __tmp_i++) {\
    if (target->mods.glue(field,_modid)[__tmp_i] == modid)\
    target->mods.glue(field,_modid)[__tmp_i] = MODID_INVAILD;}\
    for (__tmp_i = 0; __tmp_i < MAX_MOD_ITEM; __tmp_i++) {\
    if (target->mods.glue(field,_modid)[__tmp_i] == MODID_INVAILD) {\
    for (__tmp_j = __tmp_i; __tmp_j < MAX_MOD_ITEM; __tmp_j++) {\
    if (target->mods.glue(field,_modid)[__tmp_j] != MODID_INVAILD) {\
    target->mods.glue(field,_func)[__tmp_i] = target->mods.glue(field,_func)[__tmp_j];\
    target->mods.glue(field,_ctx)[__tmp_i] = target->mods.glue(field,_ctx)[__tmp_j];\
    target->mods.glue(field,_modid)[__tmp_i] = target->mods.glue(field,_modid)[__tmp_j];\
    target->mods.glue(field,_base)[__tmp_i] = target->mods.glue(field,_base)[__tmp_j];\
    target->mods.glue(field,_modid)[__tmp_j] = MODID_INVAILD; break;\
    }}}}}

// stat: 累积错误指示. rstat: 累积状态
#define exec_module_func(target, field, req_init ...) {\
    count_t __tmp_i;\
    struct glue(glue(target,_),glue(field,_req)) req = req_init;\
    for (__tmp_i = 0; __tmp_i < MAX_MOD_ITEM && target->mods.glue(field,_modid)[__tmp_i] != MODID_INVAILD; __tmp_i++) {\
    if (target->env->stat == ENV_RUNNING) \
    if (!req.rstat->req_fin) \
    if (target->mods.glue(field,_base)[__tmp_i]->stat == MOD_STAT_RUNNING) {\
    req.ctx = target->mods.glue(field,_ctx)[__tmp_i];\
    stat |= target->mods.glue(field,_func)[__tmp_i](req);}\
    }req.rstat->req_fin=true;}
